home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / texte / qed / src / find.c < prev    next >
C/C++ Source or Header  |  1998-11-09  |  30KB  |  1,319 lines

  1. #include "global.h"
  2. #include "aktion.h"
  3. #include "ausgabe.h"
  4. #include "block.h"
  5. #include "clipbrd.h"
  6. #include "comm.h"
  7. #include "edit.h"
  8. #include "event.h"
  9. #include "file.h"
  10. #include "icon.h"
  11. #include "memory.h"
  12. #include "rsc.h"
  13. #include "set.h"
  14. #include "tasten.h"
  15. #include "text.h"
  16. #include "umbruch.h"
  17. #include "window.h"
  18. #include "find.h"
  19.  
  20. extern void    menu_help(int title, int item);
  21.  
  22. /* exportierte Variablen ***************************************************/
  23.  
  24. bool                    s_grkl, s_quant, s_wort, s_vorw, s_global, s_round,
  25.                         ff_rekursiv;
  26. int                    r_modus, rp_box_x, rp_box_y;
  27. char                    r_str[HIST_LEN+1], s_str[HIST_LEN+1],
  28.                         s_history[HIST_ANZ][HIST_LEN+1],
  29.                         r_history[HIST_ANZ][HIST_LEN+1],
  30.                         ff_mask[15+1];
  31.  
  32. UMLAUTENCODING     umlaut_from, umlaut_to;
  33.  
  34. /*****************************************************************************/
  35.  
  36. #define SETANZ         5
  37.  
  38. #define M_CURSOR        0        /* Werte für modus von start_suche */
  39. #define M_TSTART        1
  40. #define M_TENDE        2
  41.  
  42. static ZEILEP     start;
  43. static int        text_len, text_x,
  44.                     last_op = -1;
  45. static long        text_y;
  46. static SET        wort_set;
  47.  
  48. /* Variablen, die über set_suchmode gesetzt werden */
  49. /* !!! muessen bei match gesichet werden !!! */
  50. static bool        quantor, vorw, grkl, wort, modus, round, line_start;
  51. static int        muster_len;
  52. static char     muster_txt[HIST_LEN+1];
  53. static char     replace_txt[HIST_LEN+1];
  54. static SET        group[SETANZ];
  55. static int        setanz;
  56. static int        delta[256];
  57.  
  58. /* lokale Prototypen *****************************************************/
  59. static bool    build_popup (char h[HIST_ANZ][HIST_LEN+1], POPUP *pop);
  60. static int    hist_popup    (char h[HIST_ANZ][HIST_LEN+1], OBJECT *tree, int obj_pos, int obj_text);
  61.  
  62. /*=======================================================================*/
  63.  
  64. static void init_suche(TEXTP t_ptr, int modus)
  65. {
  66.     if (modus == M_CURSOR)
  67.     {
  68.         start = t_ptr->cursor_line;
  69.         text_y = t_ptr->ypos;
  70.         if (vorw)
  71.         {
  72.             text_x = t_ptr->xpos;
  73.             text_len = start->len-t_ptr->xpos;
  74.             if (text_len>0)
  75.             {
  76. /*
  77.     Muß das sein? Dann findet ^G nämlich nichts, wenn der Cursor auf dem
  78.     gesuchten steht!?
  79.                 text_x++;
  80.                 text_len--;
  81. */
  82.             }
  83.             else if (!IS_LAST(start))
  84.             {
  85.                 NEXT(start);
  86.                 text_y++;
  87.                 text_x = 0;
  88.                 text_len = start->len;
  89.             }
  90.         }
  91.         else
  92.         {
  93.             text_x = 0;
  94.             text_len = t_ptr->xpos;
  95.             if (text_len>0)
  96.             {
  97. /*
  98.     Diese Zeile müßte eigentlich auch raus, damit das gefunden wird (rückwärts)
  99.     wo der Cursor 'draufsteht. Dann klappt aber der ^G nicht, da dann der
  100.     Cursor (Blockmarkierung!) wieder hinter dem gefundenen steht und so immer
  101.     wieder das gleiche findet!
  102. */
  103.                 text_len--;
  104.             }
  105.             else if (!IS_FIRST(start))
  106.             {
  107.                 VORG(start);
  108.                 text_y--;
  109.                 text_len = start->len;
  110.             }
  111.         }
  112.     }
  113.     else if (modus==M_TSTART)
  114.     {
  115.         start = FIRST(&t_ptr->text);
  116.         text_x = 0;
  117.         text_len = start->len;
  118.         text_y = 0;
  119.     }
  120.     else
  121.     {
  122.         start = LAST(&t_ptr->text);
  123.         text_x = 0;
  124.         text_len = start->len;
  125.         text_y = t_ptr->text.lines-1;
  126.     }
  127.     setcpy(wort_set,t_ptr->loc_opt->wort_set);
  128. }
  129.  
  130. static int suche1(ZEILEP col, int x, int str_len, int *such_len,
  131.                         char*(*call)(char*,int,char*,int*))
  132. /* vorw */
  133. {
  134.     char *ptr, *str, *str2;
  135.  
  136.     if (quantor)
  137.     {
  138.         if (x>0 && line_start)                                    /* Muster am Anfang finden */
  139.             return -1;
  140.         if (x+str_len<col->len && muster_len>=2 &&
  141.              muster_txt[muster_len-2]=='[' && muster_txt[muster_len-1]==0xFC)
  142.             return -1;
  143.     }
  144.     ptr = TEXT(col);
  145.     str = ptr+x;
  146.     str2 = (*call)(str, str_len, muster_txt, such_len);
  147.     if (str2==NULL) return -1;
  148.     if (wort)
  149.     {
  150.         while (!(str2==ptr || !setin(wort_set,str2[-1])) ||
  151.                  !(str2[*such_len]==EOS || !setin(wort_set,str2[*such_len])))
  152.         {
  153.             str2++;
  154.             str_len -= (int)(str2 - str);
  155.             str = str2;
  156.             str2 = (*call)(str, str_len, muster_txt, such_len);
  157.             if (str2==NULL) return -1;
  158.         }
  159.     }
  160.     return (int)(str2 - ptr);
  161. }
  162.  
  163. static int suche2(ZEILEP col, int x, int str_len, int *such_len,
  164.                         char*(*call)(char*,int,char*,int*))
  165. /* rauf */
  166. {
  167.     int    x2, merk;
  168.  
  169.     merk = 0;
  170.     while (TRUE)
  171.     {
  172.         x2 = suche1(col, x, str_len, such_len, call);
  173.         if (x2==-1) break;
  174.         x2++;                                 /* Weiter suchen */
  175.         str_len -= x2-x;                    /* Restlänge */
  176.         merk = x = x2;
  177.     }
  178.     return merk-1;
  179. }
  180.  
  181. static char *STRSTR(char *str_anf, int str_len, char *mstr_anf, int *found_len)
  182. /* Suche ohne Quantoren */
  183. {
  184.     char *mstr, *str;
  185.     int    i, mstr_len = muster_len;
  186.  
  187.     *found_len = mstr_len;
  188.     str_anf += mstr_len;
  189.     str_len -= mstr_len;
  190.     mstr_anf += mstr_len;
  191.     while (str_len>=0)
  192.     {
  193.         str = str_anf;
  194.         mstr = mstr_anf;
  195.         i = mstr_len;
  196.         while(TRUE)
  197.         {
  198.             if (*(--mstr)!=*(--str)) break;        /* Match fehlgeschlagen */
  199.             if ((--i)<=0) return(str);             /* gefunden */
  200.             if (*(--mstr)!=*(--str)) break;        /* Match fehlgeschlagen */
  201.             if ((--i)<=0) return(str);                /* gefunden */
  202.             if (*(--mstr)!=*(--str)) break;        /* Match fehlgeschlagen */
  203.             if ((--i)<=0) return(str);             /* gefunden */
  204.             if (*(--mstr)!=*(--str)) break;        /* Match fehlgeschlagen */
  205.             if ((--i)<=0) return(str);             /* gefunden */
  206.         }
  207.         i = delta[str_anf[-1]];
  208.         str_anf += i;                                        /* weiterrücken */
  209.         str_len -= i;
  210.     }
  211.     return(NULL);
  212. }
  213.  
  214. static char *STRSTR1(char *str_anf, int str_len, char *mstr_anf, int *found_len)
  215. /* Suche ohne Quantoren (Gross/Klein) */
  216. {
  217.     char *mstr, *str, s;
  218.     int    i, mstr_len = muster_len;
  219.  
  220.     *found_len = mstr_len;
  221.     str_anf += mstr_len;
  222.     str_len -= mstr_len;
  223.     mstr_anf += mstr_len;
  224.     while (str_len>=0)
  225.     {
  226.         str = str_anf;
  227.         mstr = mstr_anf;
  228.         i = mstr_len;
  229.         while (TRUE)
  230.         {
  231.             s = *(--str);
  232.             if (s>='a' && s<='z') s-=32;
  233.             else if (s=='ö') s = 'Ö';
  234.             else if (s=='ü') s = 'Ü';
  235.             else if (s=='ä') s = 'Ä';
  236.             if (*(--mstr)!=s) break;                    /* Match fehlgeschlagen */
  237.             if ((--i)<=0) return (str);                /* gefunden */
  238.         }
  239.         s = str_anf[-1];
  240.         if (s>='a' && s<='z') s-=32;
  241.         else if (s=='ö') s = 'Ö';
  242.         else if (s=='ü') s = 'Ü';
  243.         else if (s=='ä') s = 'Ä';
  244.         i = delta[s];
  245.         str_anf += i;                                        /* weiterrücken */
  246.         str_len -= i;
  247.     }
  248.     return(NULL);
  249. }
  250.  
  251. static char *STRSTR2(char *str_anf, int str_len, char *mstr_anf, int *found_len)
  252. /* Suche mit Quantoren (rekursiv) */
  253. {
  254.     char *str, *mstr, m, s;
  255.     int    len, anz;
  256.  
  257.     if (line_start)                                        /* Muster am Anfang finden */
  258.         anz = 1;
  259.     else
  260.         anz = str_len+1;                                    /* Anzahl der Tests */
  261.     while ((--anz)>=0)                                    /* auch len=0 kann Treffer sein */
  262.     {
  263.         mstr = mstr_anf;                                    /* Muster reset */
  264.         str = str_anf;                                     /* String reset */
  265.         len = str_len;
  266.         while (TRUE)
  267.         {
  268.             m = *mstr++;                                    /* neue Zeichen holen */
  269.             s = *str;
  270.             if (m==EOS)                                     /* Muster komplett gefunden */
  271.             {
  272.                 *found_len = (int)(str - str_anf);
  273.                 return str_anf;
  274.             }
  275.             if (len==0)
  276.                 s = EOS;
  277.  
  278.             if (m=='*')
  279.             {
  280.                 bool    save = line_start;
  281.  
  282.                 line_start = FALSE;
  283.                 str = STRSTR2(str, len, mstr, found_len);
  284.                 line_start = save;
  285.                 if (str==NULL)
  286.                     return NULL;
  287.                 *found_len += (int)(str - str_anf);
  288.                 return str_anf;
  289.             }
  290.             if (!grkl)
  291.             {
  292.                 if (s>='a' && s<='z') s-=32;
  293.                 else if (s=='ö') s = 'Ö';
  294.                 else if (s=='ü') s = 'Ü';
  295.                 else if (s=='ä') s = 'Ä';
  296.             }
  297.             if (m=='[')
  298.             {
  299.                 m = *mstr++;                                /* nach '[' folgt ein Infozeichen */
  300.                 if (m==0xFF)                            /* echtes '[' */
  301.                 {
  302.                     if (s!='[') break;
  303.                 }
  304.                 else if (m==0xFE)                             /* Wortende (letztes in Muster) */
  305.                 {
  306.                     if (len==0 || !setin(wort_set,s))
  307.                     {
  308.                         *found_len = (int)(str - str_anf);
  309.                         return str_anf;
  310.                     }
  311.                     break;
  312.                 }
  313.                 else if (m==0xFC)                         /* Zeilenende */
  314.                 {
  315.                     if (len==0)
  316.                     {
  317.                         *found_len = (int)(str - str_anf);
  318.                         return str_anf;
  319.                     }
  320.                     break;
  321.                 }
  322.                 else                                            /* Wildcard */
  323.                 {
  324.                     if (!setin(group[m-1],s)) break;
  325.                 }
  326.             }
  327.             else                                                /* normale Zeichen und '?' */
  328.                 if (m!=s && m!='?') break;
  329.  
  330.             if (len==0) break;
  331.             str++; len--;                                    /* nächstes Zeichen */
  332.         }
  333.         str_anf++;                                            /* String ein Zeichen weiter */
  334.         str_len--;
  335.     }
  336.     return NULL;
  337. }
  338.  
  339. /* rein : start, text_x, text_len, text_y */
  340. /* raus : start, text_x, text_len, text_y */
  341. /* -1:Abbruch, 0:nichts gefunden 1:gefunden */
  342.  
  343. static int suchen2(int *such_len)
  344. {
  345.     char*    (*call)    (char*,int,char*,int*);
  346.     long    y;
  347.     ZEILEP lauf;
  348.     int    step, x;
  349.  
  350.     x = text_x;
  351.     y = text_y;
  352.     lauf = start;
  353.     if (muster_len==0) return 0;
  354.     step = 70;
  355.     if (quantor)
  356.         call = STRSTR2;
  357.     else if (grkl)
  358.         call = STRSTR;
  359.     else
  360.         call = STRSTR1;
  361.     if (vorw)
  362.     {
  363.         while (TRUE)
  364.         {
  365.             if ((text_x=suche1(lauf,x,text_len,such_len,call))>=0)
  366.             {
  367.                 text_y = y;
  368.                 start = lauf;
  369.                 return 1;
  370.             }
  371.             NEXT(lauf); y++; x = 0; text_len = lauf->len;
  372.             if (IS_TAIL(lauf)) return 0;
  373.             if ((--step)==0)
  374.             {
  375. /*
  376.                 if (check_for_abbruch() && note(1, 2, BREAK) == 1) 
  377.                     return -1;
  378. */
  379.                 step = 70;
  380.             }
  381.         }
  382.     }
  383.     else
  384.     {
  385.         while (TRUE)
  386.         {
  387.             if ((text_x=suche2(lauf,x,text_len,such_len,call))>=0)
  388.             {
  389.                 text_y = y;
  390.                 start = lauf;
  391.                 return 1;
  392.             }
  393.             VORG(lauf);
  394.             if (IS_HEAD(lauf)) return 0;
  395.             y--;
  396.             x = 0;
  397.             text_len = lauf->len;
  398.             if ((--step)==0)
  399.             {
  400. /*
  401.                 if (check_for_abbruch() && note(1, 2, BREAK) == 1) 
  402.                     return -1;
  403. */
  404.                 step = 70;
  405.             }
  406.         }
  407.     }
  408. }
  409.  
  410. /* rein : start, text_x, text_len, text_y */
  411. /* raus : start, text_x, text_len, text_y */
  412. /* -1:Abbruch, 0:nichts gefunden 1:gefunden */
  413.  
  414. static int suchen(TEXTP t_ptr, int *such_len)
  415. {
  416.     int    erg;
  417.  
  418.     erg = suchen2(such_len);
  419.     if (erg==0 && round)
  420.     {
  421.         int    m;
  422.  
  423.         Bconout(2, 7);
  424.         if (vorw)
  425.             m = M_TSTART;
  426.         else
  427.             m = M_TENDE;
  428.         init_suche(t_ptr,m);
  429.         erg = suchen2(such_len);
  430.     }
  431.     return erg;
  432. }
  433.  
  434. /* ====================================================================== */
  435.  
  436. static void set_suchmode(char *Muster, char *Replace, bool Grkl, bool Quantor, 
  437.                                  bool Vorw, bool Wort, bool Global, bool Round)
  438. {
  439.     char    *ptr, *d, help[HIST_LEN+1];
  440.     bool    invers;
  441.  
  442.     /* Spezial für '@' am Editfeld-Anfang! */
  443.     if (Muster[0] == '\\' && Muster[1] == '@' && Quantor)
  444.         strcpy((char *)muster_txt, Muster+1);        /* \ überspringen */
  445.     else
  446.         strcpy((char *)muster_txt, Muster);
  447.  
  448.     if (Replace[0] == '\\' && Replace[1] == '@' && Quantor)
  449.         strcpy(replace_txt, Replace+1);
  450.     else
  451.         strcpy(replace_txt, Replace);
  452.     
  453.     grkl = Grkl;
  454.     quantor = Quantor;
  455.     vorw = Vorw;
  456.     wort = Wort;
  457.     round = Round;
  458.     setanz = 0;
  459.     if (!grkl) 
  460.         str_toupper((char *)muster_txt);
  461.     if (quantor)
  462.     {
  463.         d = help;
  464.         ptr = muster_txt;
  465.         if (*ptr=='^')
  466.         {
  467.             line_start = TRUE;
  468.             ptr++;
  469.         }
  470.         else
  471.             line_start = FALSE;
  472.  
  473.         for (; *ptr; ptr++)
  474.         {
  475.             *d++ = *ptr;
  476.             if (*ptr=='$' && ptr[1]==EOS)
  477.             {
  478.                 d[-1] = '[';
  479.                 *d++ = 0xFC;
  480.             }
  481.             else if (*ptr=='[' && setanz<SETANZ)
  482.             {
  483.                 char *merk = ptr;
  484.  
  485.                 ptr++;
  486.                 invers = FALSE;
  487.                 if (*ptr=='^')
  488.                 {
  489.                     invers = TRUE;
  490.                     ptr++;
  491.                 }
  492.                 setclr(group[setanz]);
  493.                 while(*ptr && *ptr!=']')
  494.                 {
  495.                     if (ptr[0]=='-' && ptr[-1]!='[' && ptr[1]!=']')
  496.                     {
  497.                         char i;
  498.  
  499.                         ptr++;
  500.                         for (i=ptr[-2]; i<*ptr; i++)
  501.                             setincl(group[setanz],i);
  502.                     }
  503.                     else
  504.                         setincl(group[setanz],*ptr++);
  505.                 }
  506.                 if (*ptr)                            /* Keine ']' gefunden */
  507.                 {
  508.                     if (invers)
  509.                         setnot(group[setanz]);
  510.                     setanz++;
  511.                     *d++ = setanz;                 /* immer einen größer (weil nie Null) */
  512.                 }
  513.                 else
  514.                 {
  515.                     *d++ = 0xFF;                    /* Echtes '[' */
  516.                     ptr = merk;                     /* Neu Scannen */
  517.                 }
  518.             }
  519.         }
  520.         if (wort && d>help)                        /* nur Worte und überhaupt ein Muster */
  521.         {
  522.             *d++ = '[';
  523.             *d++ = 0xFE;                            /* Wortende */
  524.         }
  525.         *d = EOS;
  526.         strcpy((char *)muster_txt, help);
  527.         muster_len = (int) strlen(muster_txt);
  528.     }
  529.     else
  530.     {
  531.         int i,j;
  532.  
  533.         muster_len = (int) strlen(muster_txt);
  534.         for (i=0; i<256; i++) 
  535.             delta[i] = muster_len;
  536.         j = muster_len-1;
  537.         for (i=0; i<j; i++) 
  538.             delta[muster_txt[i]] = j-i;
  539.     }
  540.     if (Global)
  541.     {
  542.         if (vorw)
  543.             modus = M_TSTART;
  544.         else
  545.             modus = M_TENDE;
  546.     }
  547.     else
  548.             modus = M_CURSOR;
  549. }
  550.  
  551. int start_find(TEXTP t_ptr, bool quiet)
  552. {
  553.     int    len, erg;
  554.  
  555.     last_op = 1;
  556.     graf_mouse(HOURGLASS, NULL);
  557.     init_suche(t_ptr, modus);            /* Suchzeiger an den Start bringen */
  558.     erg = suchen(t_ptr,&len);
  559.     graf_mouse(ARROW, NULL);
  560.     if (erg == 1 && !quiet)
  561.     {
  562.         blk_demark(t_ptr);
  563.         t_ptr->cursor_line = start;
  564.         t_ptr->xpos = text_x;
  565.         t_ptr->ypos = text_y;
  566.         make_chg(t_ptr->link,POS_CHANGE,0);
  567.         blk_mark(t_ptr,0);
  568.         t_ptr->xpos = text_x+len;
  569.         blk_mark(t_ptr,1);
  570.         restore_edit();
  571.     }
  572.     return erg;
  573. }
  574.  
  575. int start_replace(TEXTP t_ptr)
  576. {
  577.     char     *ptr;
  578.     int    delta, erg, loc_r_modus, d,
  579.             such_len, rpl_len;
  580.     long    anz;
  581.  
  582.     last_op = 2;
  583.     graf_mouse(HOURGLASS, NULL);
  584.     rpl_len    = (int) strlen(replace_txt);
  585.     anz = 0L;
  586.     init_suche(t_ptr, modus);
  587.  
  588.     /* Nur zentrieren, wenn kein andere Pos bekannt. */
  589.     if (rp_box_x == 0 && rp_box_y == 0)
  590.         form_center(repask, &d, &d, &d, &d);
  591.     else
  592.     {
  593.         repask[0].ob_x = rp_box_x;
  594.         repask[0].ob_y = rp_box_y;
  595.     }
  596.     loc_r_modus = r_modus;
  597.     
  598.     while((erg=suchen(t_ptr, &such_len))==1)
  599.     {
  600.         delta = rpl_len-such_len;
  601.         if (start->len + delta > MAX_LINE_LEN)
  602.         {
  603.             inote(1, 0, TOOLONG, MAX_LINE_LEN);
  604.             erg = -1;
  605.             break;
  606.         }
  607.         text_len = start->len-text_x;
  608.         t_ptr->cursor_line = start;
  609.         t_ptr->xpos = text_x;
  610.         t_ptr->ypos = text_y;
  611.         if (loc_r_modus != RP_ALL)             /* Optional oder einzeln */
  612.         {
  613.             blk_demark(t_ptr);
  614.             make_chg(t_ptr->link,POS_CHANGE,0);
  615.             restore_edit();
  616.             if (loc_r_modus == RP_OPT)
  617.             {
  618.                 int antw;
  619.  
  620.                 blk_mark(t_ptr,0);
  621.                 t_ptr->xpos = text_x+such_len;
  622.                 blk_mark(t_ptr,1);
  623.                 restore_edit();
  624.  
  625.                 antw = simple_mdial(repask, 0) & 0x7fff;
  626.  
  627.                 /* die Pos des Dialogs merken */
  628.                 rp_box_x = repask[0].ob_x;
  629.                 rp_box_y = repask[0].ob_y;
  630.  
  631.                 if (antw == RAALL)                    /* ab jetzt nicht mehr fragen */
  632.                     loc_r_modus = RP_ALL;
  633.                 else if (antw ==  RANEIN)            /* Nicht ersetzen */
  634.                 {
  635.                     if (vorw)
  636.                     {
  637.                         text_x++;
  638.                         text_len--;
  639.                     }
  640.                     else
  641.                     {
  642.                         text_len = text_x+such_len-1;
  643.                         text_x = 0;
  644.                     }
  645.                     continue;
  646.                 }
  647.                 else if (antw == RAENDE)            /* aufhören */
  648.                 {
  649.                     erg = -1;
  650.                     break;
  651.                 }
  652.                 blk_demark(t_ptr);
  653.             }
  654.         }
  655.         anz ++;
  656.         get_undo_col(t_ptr);
  657.         ptr = REALLOC(&start, text_x, delta);
  658.         memcpy(ptr, replace_txt, rpl_len);
  659.         t_ptr->cursor_line = start;
  660.         if (loc_r_modus != RP_ALL)
  661.         {
  662.             make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos);
  663.             restore_edit();
  664.             if (loc_r_modus == RP_FIRST) 
  665.                 break;
  666.         }
  667.         if (vorw)
  668.         {
  669.             text_x += rpl_len;
  670.             text_len += delta;
  671.             text_len -= rpl_len;
  672.         }
  673.         else
  674.         {
  675.             text_len = text_x;
  676.             text_x = 0;
  677.         }
  678.     }
  679.     graf_mouse(ARROW, NULL);
  680.     if (anz > 0L)
  681.     {
  682.         t_ptr->moved++;
  683.         make_chg(t_ptr->link,POS_CHANGE,0);         /* wg. `*'    */
  684.         if (loc_r_modus == RP_ALL)
  685.         {
  686.             if (t_ptr->block)
  687.             {
  688.                 t_ptr->p1 = get_line(&t_ptr->text,t_ptr->z1);
  689.                 t_ptr->p2 = get_line(&t_ptr->text,t_ptr->z2);
  690.                 blk_demark(t_ptr);
  691.             }
  692.             make_chg(t_ptr->link,TOTAL_CHANGE,0);
  693.         }
  694.         if (loc_r_modus != RP_FIRST)
  695.         {
  696.             char    info[30];
  697.  
  698.             sprintf(info, rsc_string(REPLACESTR), anz);
  699.             set_info(t_ptr, info);
  700.         }
  701.         if (erg!=-1)
  702.             erg = 1;
  703.     }
  704.     else
  705.         if (erg != -1) 
  706.             erg = 0;
  707.     restore_edit();
  708.     return erg;
  709. }
  710.  
  711. int do_next(TEXTP t_ptr)
  712. {
  713.     int    erg;
  714.     bool    vorw;
  715.  
  716.     vorw = (shift_pressed()) ? (!s_vorw) : s_vorw;
  717.     set_suchmode(s_str, r_str, s_grkl, s_quant, vorw, s_wort, FALSE, s_round);
  718.     if (last_op == 1)
  719.         erg = start_find(t_ptr,FALSE);
  720.     else if (last_op == 2)
  721.         erg = start_replace(t_ptr);
  722.     else
  723.         erg = -1;
  724.     return erg;
  725. }
  726.  
  727. void find_selection(TEXTP t_ptr)
  728. {
  729.     if (t_ptr->block)
  730.     {
  731.         RING    r;
  732.         
  733.         block_copy(t_ptr, &r);
  734.         if (strlen(TEXT(FIRST(&r))) > 0)
  735.         {
  736.             strncpy(s_str, TEXT(FIRST(&r)), HIST_LEN);
  737.             kill_textring(&r);
  738.             s_str[HIST_LEN] = EOS;
  739.             set_suchmode(s_str, r_str, s_grkl, s_quant, s_vorw, s_wort, FALSE, s_round);
  740.             if (start_find(t_ptr, FALSE) == 0)
  741.                 Bconout(2, 7);
  742.         }
  743.     }
  744. }
  745.  
  746.  
  747. bool filematch(char *str, char *m, int fs_typ)
  748. {
  749.     char     *where, muster[HIST_LEN+1];
  750.     int        i;
  751.     bool    gk = FALSE, old_flg[2];
  752.  
  753.     if ((str[0] == EOS) || (m[0] == EOS))
  754.         return FALSE;
  755.     
  756.     if ((m[0] == '*') && (m[1] == '.'))        /* Ist m eine Extension? */
  757.         gk = FALSE;                                    /* dann Groß == klein! */
  758.     else
  759.     {
  760.         if (fs_typ == -1)
  761.             fs_typ = fs_case_sens((char *)str);
  762.         /* Echter GRkl-Unterscheidung nur bei Minix */
  763.         gk = (fs_typ == FULL_CASE);
  764.     }
  765.  
  766.     old_flg[0] = (modus != M_CURSOR);
  767.     old_flg[1] = round;
  768.  
  769.     sprintf(muster, "^%s$", m);
  770.     set_suchmode(muster, "", gk, TRUE, TRUE, FALSE, FALSE, FALSE);
  771.     where = STRSTR2((char*)str, (int) strlen(str), muster_txt, &i);
  772.  
  773.     /* 
  774.      * Für den Fall, das ein Projekt durchsucht wird, wird filematch() für
  775.      * die Zuordnung der lokalen Optionen für jede durchsuchte Datei einmal
  776.      * aufgerufen. Damit danach die eigentlichen Such-Parameter wieder stimmen,
  777.      * der folgende Befehl!
  778.     */
  779.     set_suchmode(s_str, r_str, s_grkl, s_quant, s_vorw, s_wort, old_flg[0], old_flg[1]);
  780.  
  781.     return (where==str);
  782. }
  783.  
  784. /* Such-Dialoge *************************************************************/
  785.  
  786. static void insert_history(char h[HIST_ANZ][HIST_LEN+1], char *str)
  787. {
  788.     int    i,j;
  789.     char    old_history[HIST_ANZ][HIST_LEN+1];
  790.  
  791.     /* alte History merken */
  792.     memcpy(old_history[0], h[0], HIST_ANZ*(HIST_LEN+1));
  793.     strcpy(h[0], str);
  794.     j = 1;
  795.     /* n-1 kopieren */
  796.     for (i = 0; i < (HIST_ANZ - 1); i++)
  797.     {
  798.         /* jeden Eintrag nur einmal */
  799.         if ((old_history[i][0] != EOS) && (strcmp(old_history[i], h[0])!=0))
  800.         {
  801.             strcpy(h[j], old_history[i]);
  802.             j++;
  803.         }
  804.     }
  805. }
  806.  
  807.  
  808. static bool build_popup(char h[HIST_ANZ][HIST_LEN+1], POPUP *pop)
  809. {
  810.     char    str[HIST_LEN + 1];
  811.     int    i;
  812.  
  813.     pop->tree = NULL;            /* init */
  814.  
  815.     if (h[0][0] == EOS)
  816.         return FALSE;
  817.     
  818.     strcpy(str, " ");
  819.     strcat(str, h[0]);
  820.     create_popup(pop, HIST_ANZ, HIST_LEN + 3, str);
  821.  
  822.     for (i = 1; i < HIST_ANZ; i++)
  823.     {
  824.         if (h[i][0] != EOS)
  825.         {
  826.             strcpy(str, " ");
  827.             strcat(str, h[i]);
  828.             append_popup(pop, str);
  829.         }
  830.     }
  831.     return (pop->tree != NULL);
  832. }
  833.  
  834.  
  835. static int circle_popup(char h[HIST_ANZ][HIST_LEN+1], void *dial, OBJECT* tree, int text_obj, int pos)
  836. {
  837.     if ((pos + 1 < HIST_ANZ) && (h[pos + 1][0] != EOS))
  838.         pos++;
  839.     else
  840.         pos = 0;
  841.     set_string(tree, text_obj, h[pos]);
  842.     redraw_mdobj(dial, text_obj);
  843.     return pos;
  844. }
  845.  
  846.  
  847. /*
  848.  * Suchen/Ersetzen in Texten
  849.  * Rückgabe:     0: Abbruch
  850.  *                    1: Suchen
  851.  *                    2: Ersetzen
  852. */
  853. int replace_dial(void)
  854. {
  855.     int    antw, d, r_cycle, s_cycle;
  856.     bool    im_kreis, s_p_v, r_p_v;            /* *_popup_valid */
  857.     bool    close = FALSE;
  858.     MDIAL    *dial;
  859.     POPUP    s_pop, r_pop;
  860.     char    s[HIST_LEN+1];
  861.             
  862.     /* Klemmbrett sichern, damit die Dialog das aktuelle haben */
  863.     save_clip();
  864.  
  865.     set_state(replace, RPGLOBAL, SELECTED, s_global);
  866.     set_state(replace, RPCURSOR, SELECTED, !s_global);
  867.     set_state(replace, RPROUND, SELECTED, s_round);
  868.  
  869.     set_string(replace, RPTEXT1, s_str);
  870.     set_string(replace, RPTEXT2, r_str);
  871.     set_state(replace, RPGRKL, SELECTED, s_grkl);
  872.     set_state(replace, RPWILD, SELECTED, s_quant);
  873.     set_state(replace, RPWORT, SELECTED, s_wort);
  874.     set_state(replace, RPVORW, SELECTED, s_vorw);
  875.     set_state(replace, RPRUCKW, SELECTED, !s_vorw);
  876.     set_state(replace, RPFIRST, SELECTED, r_modus==RP_FIRST);
  877.     set_state(replace, RPALL, SELECTED, r_modus==RP_ALL);
  878.     set_state(replace, RPOPTION, SELECTED, r_modus==RP_OPT);
  879.  
  880.     s_p_v = build_popup(s_history, &s_pop);
  881.     r_p_v = build_popup(r_history, &r_pop);
  882.  
  883.     /* Popups ggf. abschalten */
  884.     set_state(replace, RPSHIST, DISABLED, !s_p_v);
  885.     set_state(replace, RPEHIST, DISABLED, !r_p_v);
  886.  
  887.     s_cycle = 0;
  888.     r_cycle = 0;
  889.     dial = open_mdial(replace, RPTEXT1);
  890.     if (dial != NULL)
  891.     {
  892.         while (!close)
  893.         {
  894.             antw = do_mdial(dial) & 0x7fff;
  895.             switch (antw)
  896.             {
  897.                 case RPSSTR :
  898.                     if (s_p_v)
  899.                         s_cycle = circle_popup(s_history, dial, replace, RPTEXT1, s_cycle);
  900.                     break;
  901.                 case RPSHIST :
  902.                     if (s_p_v)
  903.                     {
  904.                         d = handle_popup(replace, RPSHIST, s_pop.tree, 0, POP_OPEN);
  905.                         if (d > 0)
  906.                         {
  907.                             s_cycle = d;
  908.                             get_string(s_pop.tree, s_cycle, s);
  909.                             set_string(replace, RPTEXT1, s+1);
  910.                             redraw_mdobj(dial, RPTEXT1);
  911.                         }
  912.                     }
  913.                     break;
  914.         
  915.                 case RPESTR :
  916.                     if (r_p_v)
  917.                         r_cycle = circle_popup(r_history, dial, replace, RPTEXT2, r_cycle);
  918.                     break;
  919.                 case RPEHIST :
  920.                     if (r_p_v)
  921.                     {
  922.                         d = handle_popup(replace, RPEHIST, r_pop.tree, 0, POP_OPEN);
  923.                         if (d > 0)
  924.                         {
  925.                             r_cycle = d;
  926.                             get_string(r_pop.tree, r_cycle, s);
  927.                             set_string(replace, RPTEXT2, s+1);
  928.                             redraw_mdobj(dial, RPTEXT2);
  929.                         }
  930.                     }
  931.                     break;
  932.         
  933.                 case RPHELP :
  934.                     menu_help(TSEARCH, MFIND);
  935.                     set_state(replace, antw, SELECTED, FALSE);
  936.                     redraw_mdobj(dial, antw);
  937.                     break;
  938.         
  939.                 default:
  940.                     close = TRUE;
  941.                     break;
  942.             }
  943.         }
  944.         close_mdial(dial);
  945.         set_state(replace, antw, SELECTED, FALSE);
  946.         if (antw == RPOK || antw == RPERSATZ)
  947.         {
  948.             get_string(replace, RPTEXT1, s_str);
  949.             get_string(replace, RPTEXT2, r_str);
  950.             if ((strcmp(s_str, r_str) == 0) && (antw == RPERSATZ))
  951.             {
  952.                 note(1, 0, RPSAME);
  953.                 return 0;
  954.             }
  955.             s_grkl    = get_state(replace,RPGRKL, SELECTED);
  956.             s_quant    = get_state(replace,RPWILD, SELECTED);
  957.             s_wort    = get_state(replace,RPWORT, SELECTED);
  958.             s_vorw = get_state(replace,RPVORW, SELECTED);
  959.             s_global = get_state(replace,RPGLOBAL, SELECTED);
  960.             s_round    = get_state(replace,RPROUND, SELECTED);
  961.     
  962.             if (get_state(replace, RPFIRST, SELECTED))
  963.                 r_modus = RP_FIRST;
  964.             else if (get_state(replace, RPALL, SELECTED))
  965.                 r_modus = RP_ALL;
  966.             else
  967.                 r_modus = RP_OPT;
  968.     
  969.             if (s_str[0] != EOS)
  970.                 insert_history(s_history, s_str);
  971.             if (r_str[0] != EOS)
  972.                 insert_history(r_history, r_str);
  973.     
  974.             im_kreis = s_round && (antw == RPOK);    /* 'im Kreis' nur bei Suchen, nicht beim Ersetzen */
  975.             set_suchmode(s_str, r_str, s_grkl, s_quant, s_vorw, s_wort, s_global, im_kreis);
  976.             return ((antw == RPOK) ? 1 : 2);
  977.         }
  978.     }
  979.     if (s_p_v)
  980.         free_popup(&s_pop);
  981.     if (r_p_v)
  982.         free_popup(&r_pop);
  983.     return 0;
  984. }
  985.  
  986. /*
  987.  * Suchen auf Disk / in Projekt
  988. */
  989. bool findfile_dial(char *ff_path, bool in_prj)
  990. {
  991.     PATH    new_path = "", str = "";
  992.     char     s[HIST_LEN+1];
  993.     int    antw, cycle, d;
  994.     bool    close = FALSE, p_v;
  995.     MDIAL    *dial;
  996.     POPUP    pop;
  997.         
  998.     save_clip();
  999.  
  1000.     if (in_prj)                            /* Suche im Projekt */
  1001.     {
  1002.         set_string(find_obj, FFTITLE, rsc_string(FFSTR2));
  1003.         set_state(find_obj, FFSELP, DISABLED, TRUE);
  1004.         set_state(find_obj, FFREK, DISABLED, TRUE);
  1005.         set_state(find_obj, FFREK, SELECTED, FALSE);
  1006.         make_shortpath(ff_path, str, 50);
  1007.     }    
  1008.     else                                    /* Suche nach Dateien */
  1009.     {
  1010.         set_string(find_obj, FFTITLE, rsc_string(FFSTR1));
  1011.         set_state(find_obj, FFSELP, DISABLED, FALSE);
  1012.         set_state(find_obj, FFREK, DISABLED, FALSE);
  1013.         set_state(find_obj, FFREK, SELECTED, ff_rekursiv);
  1014.         strcpy(new_path, ff_path);
  1015.         if (ff_path[0] != EOS)
  1016.             make_shortpath(ff_path, str, 50);
  1017.     }
  1018.     set_string(find_obj, FFPATH, str);
  1019.     set_string(find_obj, FFMASK, ff_mask);
  1020.     set_string(find_obj, FFTEXT, s_str);
  1021.     set_state(find_obj, FFGRKL, SELECTED, s_grkl);
  1022.     set_state(find_obj, FFWILD, SELECTED, s_quant);
  1023.     set_state(find_obj, FFWORT, SELECTED, s_wort);
  1024.  
  1025.     p_v =    build_popup(s_history, &pop);
  1026.  
  1027.     /* Popup ggf. abschalten */
  1028.     set_state(find_obj, FFHIST, DISABLED, !p_v);
  1029.  
  1030.     cycle = 0;
  1031.  
  1032.     dial = open_mdial(find_obj, in_prj ? FFTEXT : FFMASK);
  1033.     if (dial != NULL)
  1034.     {
  1035.         while (!close)
  1036.         {
  1037.             antw = do_mdial(dial) & 0x7fff;
  1038.  
  1039.             switch (antw)
  1040.             {
  1041.                 case FFSTR :
  1042.                     if (p_v)
  1043.                         cycle = circle_popup(s_history, dial, find_obj, FFTEXT, cycle);
  1044.                     break;
  1045.                 case FFHIST:
  1046.                     if (p_v)
  1047.                     {
  1048.                         d = handle_popup(find_obj, FFHIST, pop.tree, 0, POP_OPEN);
  1049.                         if (d > 0)
  1050.                         {
  1051.                             cycle = d;
  1052.                             get_string(pop.tree, cycle, s);
  1053.                             set_string(find_obj, FFTEXT, s+1);
  1054.                             redraw_mdobj(dial, FFTEXT);
  1055.                         }
  1056.                     }
  1057.                     break;
  1058.  
  1059.                 case FFSELP:
  1060.                     if (select_path(new_path, rsc_string(SELPATHSTR)))
  1061.                         set_string(find_obj, FFPATH, new_path);
  1062.                     break;
  1063.     
  1064.                 case FFHELP :
  1065.                     menu_help(TSEARCH, MFIND);
  1066.                     break;
  1067.     
  1068.                 default:
  1069.                     close = TRUE;
  1070.                     break;
  1071.             }
  1072.             if (!close)
  1073.             {
  1074.                 set_state(find_obj, antw, SELECTED, FALSE);
  1075.                 redraw_mdobj(dial, antw);
  1076.             }
  1077.         }
  1078.         close_mdial(dial);
  1079.         set_state(find_obj, antw, SELECTED, FALSE);
  1080.         if (antw == FFOK)
  1081.         {
  1082.             get_string(find_obj, FFTEXT, s_str);
  1083.             get_string(find_obj, FFMASK, ff_mask);
  1084.             ff_rekursiv = get_state(find_obj, FFREK, SELECTED);
  1085.             s_grkl    = get_state(find_obj, FFGRKL, SELECTED);
  1086.             s_quant    = get_state(find_obj, FFWILD, SELECTED);
  1087.             s_wort    = get_state(find_obj, FFWORT, SELECTED);
  1088.             if (!in_prj)
  1089.                 strcpy(ff_path, new_path);
  1090.             if (s_str[0] != EOS)
  1091.                 insert_history(s_history, s_str);
  1092.             set_suchmode(s_str, "", s_grkl, s_quant, TRUE, s_wort, TRUE, FALSE);
  1093.             if (in_prj && s_str[0] == EOS)
  1094.                 return FALSE;
  1095.             else
  1096.                 return TRUE;
  1097.         }
  1098.     }
  1099.     return FALSE;
  1100. }
  1101.  
  1102.  
  1103.     
  1104. /*****************************************************************************/
  1105. /*
  1106.  * Umlaute konvertieren
  1107. */
  1108.  
  1109. static char umlaute[8][7] =
  1110. {    /* ä      Ä      ö      Ö      ü      Ü      ß    */
  1111.     { 0x84, 0x8E, 0x94, 0x99, 0x81, 0x9A, 0x9E},    /* Atari */
  1112.     { 0xE4, 0xC4, 0xF6, 0xD6, 0xFC, 0xDC, 0xDF},    /* Latin */
  1113.     { 0x8A, 0x80, 0x9A, 0x85, 0x9F, 0x86, 0xA7},    /* Mac */
  1114.     { 0x84, 0x8E, 0x94, 0x99, 0x81, 0x9A, 0xE1},    /* PC */
  1115.     {  'a',  'A',  'o',  'O',  'u',  'U',  's'},    /* LaTeX */
  1116.     {  'a',  'A',  'o',  'O',  'u',  'U',  's'},    /* HTML */
  1117.     {  'a',  'A',  'o',  'O',  'u',  'U',  's'},    /* ASCII */
  1118. };
  1119.  
  1120.  
  1121. void change_umlaute(TEXTP t_ptr)
  1122. {
  1123.     ZEILEP    lauf;
  1124.     int        x, update;
  1125.     long        l;
  1126.     bool        cont = TRUE;
  1127.     bool        changed = FALSE;
  1128.     
  1129.     lauf = FIRST(&t_ptr->text);
  1130.     if (lauf != NULL)
  1131.     {
  1132.         x = bild_pos(t_ptr->xpos, t_ptr->cursor_line, TRUE, t_ptr->loc_opt->tabsize);
  1133.         start_aktion(rsc_string(UMLAUTSTR), TRUE, t_ptr->text.lines);
  1134.         l = 0;
  1135.         if (t_ptr->text.lines < 200)
  1136.             update = 10;
  1137.         else
  1138.             update = 100;
  1139.  
  1140.         graf_mouse(HOURGLASS, NULL);
  1141.  
  1142.         while (cont && !IS_TAIL(lauf))
  1143.         {
  1144.             if (lauf->len > 0)
  1145.             {
  1146.                 int    u, xpos, len;
  1147.                 char    c;
  1148.                     
  1149.                 xpos = 0;
  1150.                 while (xpos < lauf->len)
  1151.                 {
  1152.                     c = TEXT(lauf)[xpos];
  1153.                     if (c > 127)
  1154.                     {
  1155.                         for (u = 0; u <= 7; u++)
  1156.                             if (c == umlaute[umlaut_from][u])
  1157.                                 break;
  1158.                 
  1159.                         if (u < 7)
  1160.                         {
  1161.                             changed = TRUE;
  1162.                             if (umlaut_to == LaTeX)
  1163.                             {
  1164.                                 if (lauf->len + 1 <= MAX_LINE_LEN)
  1165.                                 {
  1166.                                     TEXT(lauf)[xpos] = '"';
  1167.                                     xpos++;
  1168.                                     *(REALLOC(&lauf, xpos, 1)) = umlaute[umlaut_to][u];
  1169.                                 }
  1170.                                 else
  1171.                                     inote(1, 0, TOOLONG, MAX_LINE_LEN);
  1172.                             }
  1173.                             else if (umlaut_to == ASCII)
  1174.                             {
  1175.                                 if (lauf->len + 1 <= MAX_LINE_LEN)
  1176.                                 {
  1177.                                     TEXT(lauf)[xpos] = umlaute[umlaut_to][u];
  1178.                                     xpos++;
  1179.                                     if (u == 6)
  1180.                                         *(REALLOC(&lauf, xpos, 1)) = 's';
  1181.                                     else
  1182.                                         *(REALLOC(&lauf, xpos, 1)) = 'e';
  1183.                                 }
  1184.                                 else
  1185.                                     inote(1, 0, TOOLONG, MAX_LINE_LEN);
  1186.                             }
  1187.                             else if (umlaut_to == HTML)
  1188.                             {
  1189.                                 /* ä ß */
  1190.                                 char    new[7] = "Xuml;";
  1191.  
  1192.                                 if (u == 6)
  1193.                                     strcpy(new, "szlig;");
  1194.                                 else
  1195.                                     new[0] = umlaute[umlaut_to][u];
  1196.                                 len = (int)strlen(new);
  1197.                                 if (lauf->len + len <= MAX_LINE_LEN)
  1198.                                 {
  1199.                                     TEXT(lauf)[xpos] = '&';
  1200.                                     xpos++;
  1201.                                     INSERT(&lauf, xpos, len, new);
  1202.                                     xpos += len-1;
  1203.                                 }
  1204.                                 else
  1205.                                     inote(1, 0, TOOLONG, MAX_LINE_LEN);
  1206.                             }
  1207.                             else
  1208.                                 TEXT(lauf)[xpos] = umlaute[umlaut_to][u];
  1209.                         }
  1210.                     }
  1211.                     xpos++;
  1212.                 } /* while xpos */
  1213.             } /* while lauf */
  1214.             NEXT(lauf);
  1215.  
  1216.             l++;
  1217.             if (l % update == 0)
  1218.                 cont = do_aktion("", l);
  1219.         }
  1220.         
  1221.         graf_mouse(ARROW, NULL);
  1222.         end_aktion();
  1223.  
  1224.         if (changed)
  1225.         {
  1226.             t_ptr->moved++;
  1227.             t_ptr->cursor_line = get_line(&t_ptr->text, t_ptr->ypos);
  1228.             t_ptr->xpos = inter_pos(x, t_ptr->cursor_line, TRUE, t_ptr->loc_opt->tabsize);
  1229.             make_chg(t_ptr->link, WT_CHANGE, 0);
  1230.             make_chg(t_ptr->link, TOTAL_CHANGE, 0);
  1231.             t_ptr->max_line = NULL;
  1232.  
  1233.             if (t_ptr->loc_opt->umbrechen)
  1234.                 total_format(t_ptr);
  1235.  
  1236.             restore_edit();
  1237.         }
  1238.     }
  1239. }
  1240.  
  1241. bool umlaut_dial(void)
  1242. {
  1243.     bool    ret = FALSE, close = FALSE;
  1244.     int    antw, new_from, new_to, d;
  1245.     MDIAL    *dial;
  1246.     char    str[30];
  1247.         
  1248.     new_from = umlaut_from;
  1249.     new_to = umlaut_to;
  1250.     if (shift_pressed())                /* bei Shift: Quelle und Ziel vertauschen */
  1251.     {
  1252.         if (umlaut_to <= PC)            /* nur einbuchstabige können umgedreht werden! */
  1253.         {
  1254.             new_from = umlaut_to;
  1255.             new_to = umlaut_from;
  1256.         }
  1257.         else
  1258.         {
  1259.             Bconout(2, 7);
  1260.             return FALSE;
  1261.         }
  1262.     }
  1263.     get_string(popups, UPFROMST + new_from, str);
  1264.     set_string(umlautkonv, UVON, str);
  1265.     get_string(popups, UPTOST + new_to, str);
  1266.     set_string(umlautkonv, UNACH, str);
  1267.  
  1268.     dial = open_mdial(umlautkonv, 0);
  1269.     if (dial != NULL)
  1270.     {
  1271.         while (!close)
  1272.         {
  1273.             antw = do_mdial(dial) & 0x7fff;
  1274.             switch (antw)
  1275.             {
  1276.                 case UVSTR :
  1277.                 case UVON :
  1278.                     if (antw == UVON)
  1279.                         d = handle_popup(umlautkonv, UVON, popups, UMLAUTPOP1, POP_OPEN);
  1280.                     else
  1281.                         d = handle_popup(umlautkonv, UVON, popups, UMLAUTPOP1, POP_CYCLE);
  1282.                     if (d > 0)
  1283.                         new_from = d - UPFROMST;
  1284.                     break;
  1285.                 case UNSTR :
  1286.                 case UNACH :
  1287.                     if (antw == UNACH)
  1288.                         d = handle_popup(umlautkonv, UNACH, popups, UMLAUTPOP2, POP_OPEN);
  1289.                     else
  1290.                         d = handle_popup(umlautkonv, UNACH, popups, UMLAUTPOP2, POP_CYCLE);
  1291.                     if (d > 0)
  1292.                         new_to = d - UPTOST;
  1293.                     break;
  1294.  
  1295.                 default:
  1296.                     close = TRUE;
  1297.                     break;
  1298.             }
  1299.         }
  1300.         set_state(umlautkonv, antw, SELECTED, FALSE);
  1301.         close_mdial(dial);
  1302.         if (antw == UKSTART)
  1303.         {
  1304.             if (new_from == new_to)
  1305.             {
  1306.                 note(1, 0, NOKONV);
  1307.                 ret = FALSE;
  1308.             }
  1309.             else
  1310.             {
  1311.                 umlaut_from = new_from;
  1312.                 umlaut_to = new_to;
  1313.                 ret = TRUE;
  1314.             }
  1315.         }
  1316.     }
  1317.     return ret;
  1318. }
  1319.